#ifndef __INC_QGUVLS_H__
#define __INC_QGUVLS_H__

#ifdef _MSC_VER
#pragma once
#endif

//////////////////////////////////////////////////////////////////////////
// definition

// specific
enum qgRenderSpecific
{
	QGRSPCF_NONE,
	QGRSPCF_DRAW_2D_AUTO_SET,
	QGRSPCF_MAX_VALUE
};

// render mode
enum qgRenderMode
{
	QGRMT_NONE,
	QGRMT_SCENE,
	QGRMT_ORTHO,
};

// tm type
enum qgTmType
{
	QGTMS_WORLD,
	QGTMS_VIEW,
	QGTMS_PROJ,
	QGTMS_TEX_0,
	QGTMS_TEX_1,
	QGTMS_TEX_2,
	QGTMS_TEX_3,
	QGTMS_TEX_4,
	QGTMS_TEX_5,
	QGTMS_TEX_6,
	QGTMS_TEX_7,
	QGTMS_MAX_VALUE
};

// color format
enum qgColorFormat
{
	QGCF_NONE,

	QGCF8_L,			// l8
	QGCF16_L,			// l16

	QGCF16_RGB,			// r5 g6 b5
	QGCF16_RGBA,		// a1 r5 b5 g5

	QGCF32_RGB,			// x8 r8 g8 b8
	QGCF32_RGBA,		// a8 r8 g8 b8
	QGCF32_BGR,			// x8 b8 g8 r8
	QGCF32_BGRA,		// a8 b8 g8 r8

	QGCF16F_R,			// r16
	QGCF64F_BGRA,		// a16 b16 g16 r16

	QGCF32F_R,			// r32
	QGCF128F_BGRA,		// a32 b32 g32 r32

	QGCF_DXT1,
	QGCF_DXT2,			// do not use
	QGCF_DXT3,
	QGCF_DXT4,			// do not use
	QGCF_DXT5,

	QGCF_MAX_VALUE
};

// color flag
enum qgColorFlag
{
	QGCFF_NONE		= 0,
	QGCFF_ALPHA		= 0x0001,
	QGCFF_COMPRESS	= 0x0002,
	QGCFF_FLOAT		= 0x0004,
	QGCFF_BGR		= 0x0008,
};

// topology
enum qgTopology
{
	QGTPG_NONE,
	QGTPG_POINT_LIST,
	QGTPG_LINE_LIST,
	QGTPG_LINE_STRIP,
	QGTPG_TRI_LIST,
	QGTPG_TRI_STRIP,
	//QGTPG_TRI_FAN,	// do not support for D11 problem
};

// mask
enum qgMask
{
	QGMASK_RED   = 1,
	QGMASK_GREEN = 2,
	QGMASK_BLUE  = 4,
	QGMASK_ALPHA = 8,
	QGMASK_ALL   = QGMASK_RED | QGMASK_GREEN | QGMASK_BLUE | QGMASK_ALPHA
};

// clearance
enum qgClearance
{
	QGCLEAR_DEPTH = 1,
	QGCLEAR_STENCIL = 2,
	QGCLEAR_RENDER = 3
};

// compare op
enum qgCmpOp
{
	QGCOP_NONE,
	QGCOP_NEVER,
	QGCOP_LE,
	QGCOP_EQ,
	QGCOP_LEQ,
	QGCOP_GR,
	QGCOP_NEQ,
	QGCOP_GEQ,
	QGCOP_ALWAYS
};

// filter
enum qgFilter
{
	QGFLT_NONE,
	QGFLT_MAG_MIN_MIP_POINT,
	QGFLT_MAG_MIN_POINT_MIP_LINEAR,
	QGFLT_MAG_POINT_MIN_LINEAR_MIP_POINT,
	QGFLT_MAG_POINT_MIN_MIP_LINEAR,
	QGFLT_MAG_LINEAR_MIN_MIP_POINT,
	QGFLT_MAG_LINEAR_MIN_POINT_MIP_LINEAR,
	QGFLT_MAG_MIN_LINEAR_MIP_POINT,
	QGFLT_MAG_MIN_MIP_LINEAR,
	QGFLT_ANISOTROPIC,
	QGFLTX_POINT,
	QGFLTX_LINEAR,
	QGFLT_MAX_VALUE
};

// address
enum qgAddress
{
	QGADR_NONE,
	QGADR_WRAP,
	QGADR_MIRROR,
	QGADR_CLAMP,
	QGADR_BORDER,
	QGADR_ONCE,
};

// fill mode
enum qgFill
{
	QGFILL_POINT,
	QGFILL_WIRE,
	QGFILL_SOLID
};

// cull mode
enum qgCull
{
	QGCULL_NONE,
	QGCULL_FRONT,
	QGCULL_BACK,
};

// blend op
enum qgBlendOp
{
	QGBLO_NONE,
	QGBLO_ADD,
	QGBLO_SUB,
	QGBLO_RSUB,
	QGBLO_MIN,
	QGBLO_MAX,
	QGBLO_FMIN,
	QGBLO_FMAX,
};

// blend value
enum qgBlendValue
{
	QGBLV_NONE,
	QGBLV_ZERO,
	QGBLV_ONE,
	QGBLV_SC,
	QGBLV_SC_INV,
	QGBLV_SA,
	QGBLV_SA_INV,
	QGBLV_DA,
	QGBLV_DA_INV,
	QGBLV_DC,
	QGBLV_DC_INV,
	QGBLV_SAS,
};

// draw layout usage
enum qgDloUsage
{
	QGDLOU_POSITION,
	QGDLOU_COLOR,		// diffuse & specular
	QGDLOU_WEIGHT,		// blend weights
	QGDLOU_INDEX,		// blend indices
	QGDLOU_NORMAL,
	QGDLOU_TEXTURE,		// texture coord
	QGDLOU_TANGENT,
	QGDLOU_BINORMAL,
	QGDLOU_MAX_VALUE	// this value uses as psize in DX9
};

// draw layout type
enum qgDloType
{
	QGDLOT_FLOAT1,
	QGDLOT_FLOAT2,
	QGDLOT_FLOAT3,
	QGDLOT_FLOAT4,
	QGDLOT_UINT1,
	QGDLOT_UINT2,
	QGDLOT_UINT3,
	QGDLOT_UINT4,
	QGDLOT_HALF2,
	QGDLOT_HALF4,
	QGDLOT_BYTE2,
	QGDLOT_BYTE4,
	QGDLOT_USHORT2,
	QGDLOT_USHORT4,
	QGDLOT_UINTCOLOR,
	QGDLOT_MAX_VALUE
};

// resource type
enum qgResourceType
{
	QGRES_TEXTURE,
	QGRES_RASZ,
	QGRES_BLND,
	QGRES_SPLR,
	QGRES_SHADER,
	QGRES_BUFFER,
	QGRES_LAYOUT,
	QGRES_MAX_VALUE
};

// texture stage
enum qgStageTexture
{
	QGSGTEX_1,
	QGSGTEX_2,
	QGSGTEX_3,
	QGSGTEX_4,
	QGSGTEX_5,
	QGSGTEX_6,
	QGSGTEX_7,
	QGSGTEX_8,
	QGSGTEX_MAX_VALUE
};

// off stage
enum qgStageOffTexture
{
	QGSGOFF_1,
	QGSGOFF_2,
	QGSGOFF_3,
	QGSGOFF_4,
	QGSGOFF_MAX_VALUE
};

// vertex stage
enum qgStageVertex
{
	QGSGVERT_1,
	QGSGVERT_2,
	QGSGVERT_3,
	QGSGVERT_4,
	QGSGVERT_MAX_VALUE
};

// resource creation flag
#define QGRESF_NONE							0
#define QGRESF_DYNAMIC						0x0001			// freq writing
#define QGRESF_LOCAL						0x0002			// local system memory if function available
#define QGRESF_INIT							0x0008			// data settle width initialize data
#define QGRESF_IMMUTABLE					QGRESF_INIT

// resource enter flag
#define QGENTF_NONE							0
#define QGENTF_READ							0x0001
#define QGENTF_WRITE						0x0002
#define QGENTF_READWRITE					(QGENTF_READ | QGENTF_WRITE)

// roam alias
#define QGROIS_RASZ							QGROAM_RES_1
#define QGROIS_BLND							QGROAM_RES_2
#define QGROIS_SPLR							QGROAM_RES_3
#define QGROIS_LAYOUT						QGROAM_RES_4
#define QGROIS_TEXTURE						QGROAM_RES_5
#define QGROIS_DEPTH_BUFFER					QGROAM_RES_6
#define QGROIS_EVENT						QGROAM_EVENT
#define QGROIS_ATTR							QGROAM_MTL_1
#define QGROIS_SHADER						QGROAM_MTL_2
#define QGROIS_MTRL							QGROAM_MTL_3
#define QGROIS_OBJ							QGROAM_OBJ_1
#define QGROIS_SUB							QGROAM_OBJ_2
#define QGROIS_NODE							QGROAM_OBJ_3


//////////////////////////////////////////////////////////////////////////
// supp

// viewport
struct qgViewPort
{
	tpl::Point			loc;
	tpl::Point			size;
	tpl::Vec2			depth;
	float				aspect;
};

// screen desc
struct qgScreenDesc
{
	kint				dstn;

	kint				width;
	kint				height;
	kint				freq;

	kint				internal_fmt;
	kint				internal_type;
};

// adapter desc
struct qgAdapterDesc
{
	kint				index;
	klong				mem;
	tpl::BlueStr<260>	desc;
};

// pixel property
struct qgPixelProp
{
	qgColorFormat		fmt;
	const char*			name;
	kbyte				bpp;
	kbyte				rr, rl;
	kbyte				gr, gl;
	kbyte				br, bl;
	kbyte				ar, al;
	kint				flags;
	bool				alpha;
};

//
namespace qgColorSupp
{
	KAPI kbool TestAlpha(qgColorFormat fmt);
	KAPI const qgPixelProp& ToPixelProp(qgColorFormat fmt);

	KAPI kuint UnsafePackPixel(qgColorFormat fmt, kbyte r, kbyte g, kbyte b, kbyte a);

	inline kuint PackPixel(const qgPixelProp& prop, kbyte r, kbyte g, kbyte b, kbyte a)
	{
		return ((kuint)(
			((a >> prop.ar) << prop.al) |
			((r >> prop.rr) << prop.rl) |
			((g >> prop.gr) << prop.gl) |
			((b >> prop.br) << prop.bl)));
	}
};

//
namespace qgResSupp
{
	KAPI kint LayoutTypeToSize(qgDloType type);
	KAPI const char* ShaderTypeToString(kint/*qgShaderType*/ type);
	KAPI const char* ShaderDataToString(kint/*qgShaderData*/ type);
}

// 
namespace qgTosSupp
{
	KAPI const char* ResourceTypeToString(qgResourceType type);
};


//////////////////////////////////////////////////////////////////////////
// vertex params

//
struct qgVertexWeight
{
	kbyte				i[4];
	float				w[4];
};

//
struct qgVertexWeightItem
{
	kint				w;
	kint				i;
};

//
struct qgVertexCoef
{
	kint				c0;
	kint				c1;
};


//////////////////////////////////////////////////////////////////////////
// camera params

//
struct qgParamProj
{
	float				fov;
	float				aspect;
	tpl::Vec2			z;
};

// 
struct qgParamView
{
	tpl::Vec3			at;
	tpl::Vec3			up;
	tpl::Vec3			ah;
};

//
struct qgParamCamera
{
	tpl::Mat4			proj;
	tpl::Mat4			view;

	tpl::Mat4			invv;
	tpl::Mat4			vipr;
};


//////////////////////////////////////////////////////////////////////////
// file wrap

// 
struct qgFwHsHead
{
	kuint				hdr;
	kushort				version;
	kushort				revision;
	klong				timestamp;
};

//
struct qgFwHsTail
{
	kuint				hdr;
	kushort				version;
	kushort				revision;
};

//
struct qgFwHsItem
{
	kuint				hdr;
	kushort				type;
	kushort				version;
	kuint				length;
	kuint				reserved;
};

//
struct qgFwHxp
{
	kuint				count;
	kint				insts;
	kushort				framepersecond;
	kushort				width;
	kushort				height;
	kushort				bpp;
};

//
enum qgHsItem
{
	QGHI_HXP = 0x1005,
};

//
namespace qgFwSupp
{
	KAPI bool CheckHeadAndTail(kStream* stm);
	KAPI bool CheckHeadAndTail(kconstpointer data, kint size);

}

#endif	// __INC_QGUVLS_H__
